from re import S
import dashscope
import json
from typing import Dict, List, Any, Optional
from dashscope import Generation
import weather_function_call
import gaode_nearby_places
import websearch_function_call

# 设置 API Key（需要用户自己配置）
dashscope.api_key = "***"

class QwenFunctionCall:
    """通义千问 Function Call 处理类"""
    
    def __init__(self, api_key: Optional[str] = None):
        if api_key:
            dashscope.api_key = api_key
   
    def search_info(self, query: str, category: str = "general") -> Dict[str, Any]:
        """搜索信息的模拟函数"""
        return {
            "query": query,
            "category": category,
            "results": [
                {"title": f"关于 {query} 的信息1", "summary": "这是搜索结果的摘要信息"},
                {"title": f"关于 {query} 的信息2", "summary": "这是另一个搜索结果的摘要"}
            ],
            "count": 2
        }
    
    """获取函数定义 todo 改成读取配置文件"""
    def get_function_definitions(self, function_choice: list = None) -> List[Dict[str, Any]]:
        """获取可用的函数定义
        Args:
            function_choice: 选择使用的函数列表，如果为None则返回所有函数
        Returns:
            List[Dict[str, Any]]: 函数定义列表
        """
        all_functions = [
            {
                "type": "function",
                "function": weather_function_call.weather_query_schema
            },
            {
                "type":"function",
                "function": gaode_nearby_places.nearby_places_schema
            },
            {
                "type": "function",
                "function": websearch_function_call.web_search_schema
            }
        ]
        filtered_functions = []
        # 如果没有指定函数选择，返回空函数
        if function_choice is None or len(function_choice) == 0:
            return filtered_functions
        
        # 根据function_choice过滤函数
        for func in all_functions:
            # 获取函数名称
            func_name = ""
            if isinstance(func["function"], dict) and "name" in func["function"]:
                func_name = str(func["function"]["name"])
            
            # 将function_choice中的每个元素转换为字符串进行比较
            for choice in function_choice:
                if str(choice) == func_name:
                    filtered_functions.append(func)
                    break
        
        print("filtered_functions:", filtered_functions)
        return filtered_functions

    """动态匹配函数"""
    def execute_function(self, function_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
        """执行指定的函数"""
        try:
            if function_name == "get_weather":
                return weather_function_call.get_weather(**arguments)
            elif function_name == "search_nearby_places":
                # 构建function_call对象
                function_call = {
                    "name": function_name,
                    "arguments": json.dumps(arguments)
                }
                return gaode_nearby_places.function_call_handler(function_call)
            elif function_name == "web_search":
                # 构建function_call对象
                function_call = {
                    "name": function_name,
                    "arguments": json.dumps(arguments)
                }
                print("web search innput log",function_call)
                return websearch_function_call.function_call_handler(function_call)
            else:
                return {"error": f"未知的函数: {function_name}"}
        except Exception as e:
            return {"error": f"执行函数时出错: {str(e)}"}
    
    """对话方法"""
    def chat_with_functions(self, user_message: str, function_choice: list = None, api_key: str = None) -> Dict[str, Any]:
        """与通义千问进行带函数调用的对话
        
        Args:
            user_message: 用户消息
            function_choice: 选择使用的函数列表，如果为None则使用所有函数
            api_key: 通义千问API密钥
            
        Returns:
            Dict[str, Any]: 对话结果
        """
        # apikey 校验
        if api_key:
            dashscope.api_key = api_key
        
        if not dashscope.api_key:
            return {
                "error": "请先设置 API Key",
                "message": "需要配置通义千问的 API Key 才能使用此功能"
            }
        
        try:
            # 构建消息
            messages = [
                {
                    "role": "user",
                    "content": user_message
                }
            ]
            chioceFucntion=self.get_function_definitions(function_choice)
            print("选中的FunctionCall:",chioceFucntion)
            print("开始调用大模型。。。")
            # 调用通义千问 API
            response = Generation.call(
                model="qwen-max",
                api_key=api_key,
                messages=messages,
                tools=chioceFucntion,
                result_format='message'
            )
            print("response:", response)
            if response.status_code == 200:
                assistant_message = response.output.choices[0].message
                if assistant_message.get('tool_calls'):
                    print("检查到有functioncall 调用，开始配置参数")
                    tool_call = assistant_message['tool_calls'][0]
                    function_call = tool_call.get('function')
                    function_args = json.loads(function_call.get('arguments', '{}'))
                    
                    # 执行函数
                    print("执行函数调用")
                    function_name = function_call.get('name', '')
                    print("function_name:", function_name)
                    function_result = self.execute_function(function_name, function_args)
                    print("获取执行结果：装入下次请求",function_result)
                    # 将函数调用结果添加到消息历史
                    messages.append({
                        "role": "assistant",
                        "content": None,
                        "tool_calls": [{
                            "id": tool_call.get('id'),
                            "type": "function",
                            "function": function_call
                        }]
                    })

                    messages.append({
                        "role": "tool",
                        "tool_call_id": tool_call.get('id'),
                        "content": json.dumps(function_result, ensure_ascii=False)
                    })
                    
                    # 再次调用 API 获取最终回复
                    print("再次调用 API 获取最终回复")
                    final_response = Generation.call(
                        model="qwen-max",
                        messages=messages,
                        api_key=api_key,
                        result_format='message'
                    )
                    
                    if final_response.status_code == 200:
                        final_message = final_response.output.choices[0].message.content
                        return {
                            "response": final_message,
                            "function_calls": function_result,
                            "status": "success"
                        }
                    else:
                        return {
                            "error": "获取最终回复失败",
                            "function_calls": function_result,
                            "status": "partial_success"
                        }
                # 没有函数调用，直接返回回复
                return {
                    "response": assistant_message.content,
                    "function_calls": [],
                    "status": "success"
                }
            else:
                return {
                    "error": f"API 调用失败: {response.message}",
                    "status": "error"
                }
                
        except Exception as e:
            return {
                "error": f"调用通义千问时出错: {str(e)}",
                "status": "error"
            }
